<template>
  <el-card>
    <el-form
      label-width="100px"
      :model="spuInfo"
      :rules="spuRules"
      ref="spuFormRef"
    >
      <el-form-item label="SPU名称" prop="spuName">
        <el-input v-model="spuInfo.spuName" placeholder="SPU名称"></el-input>
      </el-form-item>
      <el-form-item label="SPU品牌" prop="tmId">
        <el-select v-model="spuInfo.tmId" placeholder="请选择品牌">
          <el-option
            v-for="tm in trademarkList"
            :label="tm.tmName"
            :value="tm.id"
            :key="tm.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="SPU描述" prop="description">
        <el-input
          v-model="spuInfo.description"
          type="textarea"
          :rows="4"
        ></el-input>
      </el-form-item>
      <el-form-item label="SPU图片" prop="spuImageList">
        <el-upload
          v-model:file-list="fileList"
          :action="`${BASE_URL}/admin/product/fileUpload`"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :on-success="handleAvatarSuccess"
          :before-upload="beforeAvatarUpload"
        >
          <el-icon>
            <Plus />
          </el-icon>
        </el-upload>

        <el-dialog v-model="dialogVisible">
          <img w-full :src="dialogImageUrl" alt="Preview Image" />
        </el-dialog>
      </el-form-item>
      <el-form-item label="销售属性" prop="spuSaleAttrList">
        <el-select
          v-model="spuInfo.spuSaleAttr"
          :placeholder="`还有${filterBaseSaleAttrList.length}个销售属性`"
        >
          <el-option
            v-for="baseSaleAttr in filterBaseSaleAttrList"
            :label="baseSaleAttr.name"
            :value="baseSaleAttr.name"
          />
        </el-select>
        <el-button
          type="primary"
          :disabled="!spuInfo.spuSaleAttr"
          :icon="Plus"
          style="margin-left: 10px"
          @click="toAddSpuSaleAttr"
          >添加销售属性</el-button
        >
        <el-table border :data="spuInfo.spuSaleAttrList" style="margin: 10px 0">
          <el-table-column
            label="序号"
            type="index"
            align="center"
            width="80"
          ></el-table-column>
          <el-table-column
            label="属性名"
            prop="saleAttrName"
            width="120"
          ></el-table-column>
          <el-table-column label="属性值名称列表">
            <template v-slot="{ row }">
              <el-tag
                style="margin-right: 4px"
                v-for="(tag, index) in row.spuSaleAttrValueList"
                :key="tag"
                class="mx-1"
                closable
                :disable-transitions="false"
                @close="handleClose(row, tag, index)"
              >
                {{ tag.saleAttrValueName }}
              </el-tag>
              <el-input
                style="width: 80px"
                v-if="row.inputVisible"
                ref="InputRef"
                v-model="inputValue"
                class="ml-1 w-20"
                size="small"
                @keyup.enter="handleInputConfirm(row)"
                @blur="handleInputConfirm(row)"
              />
              <el-button
                v-else
                class="button-new-tag ml-1"
                size="small"
                @click="showInput(row)"
              >
                + New
              </el-button>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="150">
            <template v-slot="{ row, $index }">
              <el-popconfirm
                confirm-button-text="确定"
                cancel-button-text="取消"
                :icon="InfoFilled"
                icon-color="#626AEF"
                title="真的要删除此销售属性吗?"
                @confirm="toRemoveAttr($index)"
                @cancel="cancelEvent"
              >
                <template #reference>
                  <el-button
                    type="danger"
                    size="small"
                    :icon="Delete"
                  ></el-button>
                </template>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-button
        style="margin-left: 100px"
        type="primary"
        @click="submitSpuForm(spuFormRef)"
        >保存</el-button
      >
      <el-button @click="emits('setShowStatus', ShowStatus.SPU_LIST)"
        >取消</el-button
      >
    </el-form>
  </el-card>
</template>

<script lang="ts">
export default {
  name: 'SpuForm',
};
</script>
<script lang="ts" setup>
import { ref, nextTick, onMounted, reactive, computed } from 'vue';
import { Plus, Delete, InfoFilled } from '@element-plus/icons-vue';

import {
  ElMessage,
  ElInput,
  type UploadProps,
  type UploadUserFile,
  ElMenu,
} from 'element-plus';
import {
  reqGetAllBaseSaleAttrListData,
  reqGetAllTrademarkListData,
  reqGetSpuImageListData,
  reqGetSpuSaleAttrListData,
  reqSaveSpuInfoData,
  reqUpdateSpuInfoApi,
} from '@/api/product/spu';
import type { FormInstance, FormRules } from 'element-plus';
import { ShowStatus } from '../types';
import { useCategoryListStore } from '@/stores/categoryList';
const categoryStore = useCategoryListStore();
const emits = defineEmits(['setShowStatus', 'aaa', 'bbb']);
const props = defineProps(['currentSpuInfo']);
const inputValue = ref('');

const InputRef = ref<InstanceType<typeof ElInput>>();

const spuFormRef = ref<FormInstance>();

const fileList = ref<UploadUserFile[]>([]);
const BASE_URL = import.meta.env.VITE_API_URL;
const spuInfo = reactive({
  spuName: '', // spu名称
  tmId: '', // 品牌对应的id
  description: '', // spu描述
  spuImageList: [], // 上传的图片
  spuSaleAttrList: [], // 相关的销售属性及属性值
  category3Id: -1, // 3id
  spuSaleAttr: '', // 表示spu的销售属性名  是后来额外添加的
  // 将待编辑的数据展开到这里来
  ...props.currentSpuInfo,
});
const dialogImageUrl = ref('');
const dialogVisible = ref(false);

const trademarkList = ref([]);
const baseSaleAttrList = ref([]);

// 书写校验规则
const spuRules = reactive<FormRules>({
  spuName: [
    { required: true, message: '请填写Spu名称', trigger: 'blur' },
    { min: 2, max: 10, message: '长度应该在2--10之间', trigger: 'blur' },
  ],
  tmId: [
    {
      required: true,
      message: '请选择一个品牌',
      trigger: 'change',
    },
  ],
  description: [{ required: true, message: '请输入Spu描述', trigger: 'blur' }],
  spuImageList: [
    {
      required: true,
      type: 'array',
      message: '请至少上传一张图片',
      trigger: 'change',
    },
  ],
  spuSaleAttrList: [
    {
      required: true,
      type: 'array',
      message: '请至少添加一个销售属性',
      trigger: 'change',
    },
  ],
});



// 1. 当页面挂载完毕的时候 就可以来获取所有的品牌和销售属性数据
onMounted(async () => {
  try {
    let promises = [
      reqGetAllTrademarkListData(),
      reqGetAllBaseSaleAttrListData(),
    ];

    const { id } = spuInfo;
    if (id) {
      promises = promises.concat([
        reqGetSpuImageListData(id),
        reqGetSpuSaleAttrListData(id),
      ]);
    }
    const [
      responseTrademarkList,
      responseBaseSaleAttrList,
      responseSpuImageList,
      responseSpuSaleAttrList,
    ] = await Promise.all(promises);
    trademarkList.value = responseTrademarkList;
    baseSaleAttrList.value = responseBaseSaleAttrList;

    if (responseSpuImageList && responseSpuSaleAttrList) {
      fileList.value = responseSpuImageList.map((item) => {
        return {
          ...item,
          // 为了让图片能在照片墙上显示出来
          name: item.imgName,
          url: item.imgUrl,
        };
      });

      spuInfo.spuImageList = responseSpuImageList;
      spuInfo.spuSaleAttrList = responseSpuSaleAttrList;
    }
  } catch (err) {
    ElMessage.error('获取属性失败了');
  }
});

// 2. 上传图片成功后 收集上传了的图片链接地址
const handleAvatarSuccess: UploadProps['onSuccess'] = (
  response,
  uploadFile,
  uploadFiles
) => {
  spuInfo.spuImageList.push({
    imgName: uploadFile.name,
    imgUrl: response.data,
  });
  
  //1. 清除图片的校验规则
  spuFormRef.value?.clearValidate(['spuImageList']);
};

// 3. 图片上传前的校验
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  const imgArr = ['image/jpeg', 'image/png'];
  if (!imgArr.includes(rawFile.type)) {
    ElMessage.error('图片格式只能是jpg,jpeg或png,请重新选择');
    return false;
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error('图片大小不能超过2M,请重新选择');
    return false;
  }
  return true;
};

// 4. 删除图片
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  spuInfo.spuImageList = uploadFiles.map((item) => {
    return {
      imgName: item.name,
      imgUrl: item.response?.data || item.url,
    };
  });
};

// 5. 预览图片
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};

// 6. 添加销售属性
const toAddSpuSaleAttr = () => {
  // 1 判断之前的销售属性那一行中是否添加了销售属性值
  const spuSaleAttrList = spuInfo.spuSaleAttrList;
  if (
    spuSaleAttrList.length &&
    spuSaleAttrList.some((item) => item.spuSaleAttrValueList.length === 0)
  ) {
    ElMessage.warning('属性值不能为空,请添加');
    return;
  }

  // 2 获取基本销售属性对应的id
  const id = baseSaleAttrList.value.find(
    (item) => item.name === spuInfo.spuSaleAttr
  ).id;

  // 3 添加销售属性
  spuInfo.spuSaleAttrList.push({
    inputVisible: false, // 额外添加一个销售属性值按钮和输入框切换的标识
    baseSaleAttrId: id,
    saleAttrName: spuInfo.spuSaleAttr,
    spuSaleAttrValueList: [],
  });

  // 4 清空下拉框中属性名的显示
  spuInfo.spuSaleAttr = '';
};

// 7. 使用计算属性 来实现添加销售属性后移除的效果
const filterBaseSaleAttrList = computed(() => {
  return baseSaleAttrList.value.filter((baseSaleAttr) => {
    return !spuInfo.spuSaleAttrList.find(
      (item) => baseSaleAttr.name === item.saleAttrName
    ); // 这个才是对的
  });
});

// 8. 删除销售属性的添加
const toRemoveAttr = (index) => {
  spuInfo.spuSaleAttrList.splice(index, 1);
  ElMessage.success('删除销售属性成功了');
};
const cancelEvent = () => {
  ElMessage.info('取消了删除销售属性');
};

// 9. 单击添加销售属性值按钮时 进行切换
const showInput = (row) => {
  row.inputVisible = true;
  nextTick(() => {
    InputRef.value!.input!.focus();
  });
};

// 10. 收集添加的销售属性值
const handleInputConfirm = (row) => {
  if (inputValue.value) {
    // 判断一下，添加的销售属性值是否和之前的重复
    if (
      row.spuSaleAttrValueList.find(
        (item) => item.saleAttrValueName === inputValue.value
      )
    ) {
      ElMessage.warning('此属性值已经添加过了,请更换一个');

      // inputVisible.value = false; 不要使用公共的这个inputVisible
      row.inputVisible = false;
      inputValue.value = '';
      return; // 不要向下执行了
    }

    row.spuSaleAttrValueList.push({
      baseSaleAttrId: row.baseSaleAttrId,
      saleAttrName: row.saleAttrName,
      saleAttrValueName: inputValue.value,
    });
  }
  // inputVisible.value = false; 不要使用公共的这个inputVisible
  row.inputVisible = false;
  inputValue.value = '';
};

// 11. 删除销售属性值
const handleClose = (row, tag, index) => {
  row.spuSaleAttrValueList.splice(index, 1);
};

// 12. 添加spuInfo
const submitSpuForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      // 1 在直接的提交之前 再做一次校验 就是验证销售属性中的属性值必须不能有空项
      const spuSaleAttrList = spuInfo.spuSaleAttrList;
      if (
        spuSaleAttrList.length &&
        !spuSaleAttrList.every((item) => item.spuSaleAttrValueList.length)
      ) {
        ElMessage.warning('有销售属性的属性值为空,请检查或添加...');
        return;
      }

      // 2 发送 请求 去添加spuInfo
      spuInfo.category3Id = categoryStore.category3Id as number;

      if (spuInfo.id) {
        await reqUpdateSpuInfoApi(spuInfo);
      } else {
        await reqSaveSpuInfoData(spuInfo);
      }

      // 3 提示一下用户
      ElMessage.success('操作spu成功了!!!');

      // 4 跳转到列表页
      emits('setShowStatus', ShowStatus.SPU_LIST);
    } else {
      console.log('!!!000', fields);
    }
  });
};
</script>
<style></style>
